package com.mbengue.corp.apr.ra.rss;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class RSSFeedParser {
  public static final String TITLE = "title";
  public static final String DESCRIPTION = "description";
  public static final String LINK = "link";
  public static final String ITEM = "item";
  public static final String PUB_DATE = "pubDate";
  private final URL url;
  private Document document;

  public RSSFeedParser(String feedUrl) {
    try {
      this.url = new URL(feedUrl);
    } catch (MalformedURLException e) {
      throw new RuntimeException(e);
    }
  }

  public List<FeedMessage> readFeed() {
    List<FeedMessage> messages = new ArrayList<FeedMessage>();
    try {
      // Set header values intial to the empty string
      String description = "";
      String title = "";
      String link = "";
      String pubdate = "";
      read();
      NodeList items = document.getElementsByTagName(ITEM);
      for (int index = 0; index < items.getLength(); index++) {
        Node item = items.item(index);
        description = getValueFromXpath(item, DESCRIPTION);
        title = getValueFromXpath(item, TITLE);
        link = getValueFromXpath(item, LINK);
        pubdate = getValueFromXpath(item, PUB_DATE);
        messages.add(new FeedMessage(title, description, link, pubdate));
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return messages;
  }

  private void read() {
    try {
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      InputStream input = url.openStream();
      setDocument(builder.parse(input));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public void setDocument(Document document) {
    this.document = document;
  }

  public String getValueFromXpath(Node node, String xpath) throws XPathExpressionException {
    XPath xpa = XPathFactory.newInstance().newXPath();
    XPathExpression expr = xpa.compile(xpath);
    return (String) expr.evaluate(node, XPathConstants.STRING);
  }
}
